#pragma once

#include "Frog.h"
#include "Drainage.h"
#include "Rail.h"
#include "Drawable.h"
#include "Resolution.h"
#include <list>
#include <time.h>
#include "Sketcher.h"
#include "Velocity.h"
#include "ballType.h"
#include "Position.h"
#include "DrawableElement.h"
#include "Source.h"
#include "Timer.h"
#include "BallCollisionException.h"
#include "BallRailIntersectionException.h"
#include "Vida.h"
#include "Bonuz.h"
#include <vector>
#include <stack>


class Stage : public Element, public Drawable{

	// Attributes:
public: Timer ticks;
		Position* Center;

private: Score* score;
private: Vida* vida;
private: Frog* frog;   

private: time_t tAct;    

private: Ball* activeBall;
private: Position mousePosition;
private: Position lastMousePosition;
private: bool mouseSetted;
private: bool laserOn;
/*Bola activa y secundaria para mostrar en el escenario a modo informativo*/
private: Ball* showedActiveBall;
private: Ball* showedSecondaryBall;
		 int initialBallsNumber;
		 
/*-------------------------------------------------------------------------*/

private: Drainage* drainage;    
private: Rail* rail;
public: void setLaserOn();
public: void setLaserOff();
private: Position * position;
private: int countCrashedBalls(int position,int * from, int* to);

private: Texture * texture;

private: Color * elementColor;

private: Color * lineColor;

private: Resolution * resolution;
		 
private: Resolution * drawableArea;

private: Sketcher* sketcher;

private: Velocity* velocity;

private: Source* source;

private: list<ballType*> ballTypes;

private: vector<Ball*> * railBalls;

public: stack<Ball*> * accumulatedBalls;

private: list<Bonuz*> * bonusBalls;

private: Bonuz* activeBounus;

private: Bonuz* activatedBounus;

private: list<DrawableElement*> * obstacles;

private: int ballsNumber; 

private: int lifesNumeber;

private: bool hasActiveBall;

public: int ballsCounter;

public: float accumulatedTime;
		
private: float initialVelocityModule;
		 
		 // Methods:
public: void setMousePosition(int x,int y);

public: void checkBalls();

public: void showDirection();

private: void moveTheRailBalls(float time,int sinceIndex,int untilIndex,bool moveEvenStoped);

public: void refrehBallsView(Ball*,Ball*);

private: void clearAllBalls();

private: void clearBall(Ball* ball);

public: bool getHasActiveBall();

public: void setHasActiveBall(bool hasActiveBall);
		float accumulatedGenerationTime;

public: list<DrawableElement*> * getObstacles();

public: Drainage* getDrainage();

public: void addBall(Ball* ball);

public: Frog* getFrog();

public: Rail* getRail();

public: Ball* getActiveBall();

public: void setActiveBall(Ball * ball);

public: void setDrainage(Drainage * drainage);

public: void setFrog(Frog* frog);

public: void setRail(Rail* rail);

public: bool hasExploted(int insertedPosition);

public: void reversePowerOn();

public: void reversePowerOff();

public: void addElement(Element * element);
		/*-------------Drawable interface--------------------*/
public: virtual void setPosition(Position *position);

public: virtual Position *getPosition();

public: virtual Texture *getTexture();

public: virtual void setTexture(Texture *texture);

public: virtual Color * getElementColor();

public: virtual void setElementColor(Color * color);

public: virtual Color * getLineColor();

public: virtual void setLineColor(Color * color);

public: Resolution * getResolution(void);

public: void setResolution(Resolution * resolution);
		
public: bool outOfDrawableArea(Ball* ball);

public: Resolution * getDrawableArea(void);

public: void setDrawableArea(Resolution * drawableArea);

public: virtual void draw(void);

public: virtual void initialize(void);

public: virtual float getMinXPos();

public: virtual float getMinYPos();

public: virtual float getMaxXPos();

public: virtual float getMaxYPos();

public: virtual int getBallsNumber();

public: virtual void setBallsNumber(int ballsNumber);

public: virtual Velocity* getVelocity();

public: virtual void setVelocity(Velocity *velocity);
		void setVelocity(float module);
public: virtual int getLifesNumeber();

public: virtual void setLifesNumeber(int lifesNumeber);

public: virtual void addBallType(ballType*);

public: virtual list<ballType*> getBallTypes();

public: virtual list<Bonuz*> *getBonusBalls();

public: virtual Bonuz* getActiveBonus();

public: virtual Bonuz* getActivatedBonus();

public: virtual void addBonusBall(Bonuz*);

public: virtual void setActiveBonus(Bonuz*);

public: virtual void setActivatedBonus(Bonuz*);

public: virtual void setSource(Source*);

public: virtual Source* getSource();

public: virtual Score* getScore();

public: virtual Vida* getVida();
public: virtual void setVida(Vida* vida);

public: virtual vector<Ball*> *getRailBalls();

public: float actualPercentage;

public: virtual void addBallToRail(Ball*);

public: Ball * Stage::spitRailBalls();

public: float getInitialVelocityModule();

public: void setInitialVelocityModule(float initialVelocityModule);

public: Ball* getShowedActiveBall();

public: Ball* getShowedSecondaryBall();

public: void setShowedActiveBall(Ball*);

public: void setShowedSecondaryBall(Ball*);

public: float getRailDelay();

public: float points;

public: int counter;

public: void checkBonuzCollision();

public: Position* getLastMousePosition();
	
		
/*------------------- Constructor --------------------*/
public: Stage();

public: virtual ~Stage();
		void setRailBalls(vector<Ball*> * balls);
		void appendBall(Ball* ball);
		Ball * inspectBallsCollision( Ball* ball );
		void gameOver(void);
		void resetStage(void);
		void modifyVelocityPercentage(int singum);
		bool isReverseOn;
};
